/*
 * Copyright 2009 Sven Meier
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package sk.fiit.icp.event.components;

import java.util.Set;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.ContextRelativeResource;
import org.apache.wicket.spring.injection.annot.SpringBean;

import sk.fiit.icp.data.Event;
import sk.fiit.icp.event.view.RegistrationForm;
import sk.fiit.icp.service.EventService;
import sk.fiit.icp.service.SessionService;
import wicketdnd.DragSource;
import wicketdnd.DropTarget;
import wicketdnd.Location;
import wicketdnd.Operation;
import wicketdnd.Reject;
import wicketdnd.Transfer;
import wickettree.DefaultNestedTree;
import wickettree.NestedTree;

/**
 * @author Sven Meier
 */
public abstract class TreeExample extends Example {

	@SpringBean(name = "eventService")
	EventService eventService;
	

	@SpringBean(name = "sessionService")
	SessionService sessionService;

	public TreeExample(String id, final RegistrationForm regForm) {
		super( id );

		final FooTreeProvider provider = new FooTreeProvider( regForm );
		final NestedTree<Event> tree = new DefaultNestedTree<Event>( "tree", provider ) {
			@Override
			protected Component newContentComponent(String arg0, IModel<Event> arg1) {
				Component component = super.newContentComponent( arg0, arg1 );
				component.setOutputMarkupId( true );
				return component;
			}
		};

		tree.add( new DragSource() {
			@Override
			public Set<Operation> getOperations() {
				return dragOperations();
			}

			@Override
			public String[] getTypes() {
				return types();
			}

			@Override
			public void onAfterDrop(AjaxRequestTarget target, Transfer transfer) {
				if ( transfer.getOperation() == Operation.MOVE ) {
					Event event = transfer.getData();

					provider.remove( event );
					event.remove();

					target.add( tree );
				}
			}
		}.drag( "span.tree-content" ) );
		tree.add( new DropTarget() {
			@Override
			public Set<Operation> getOperations() {
				return dropOperations();
			}

			@Override
			public String[] getTypes() {
				return types();
			}

			@Override
			public void onDrag(AjaxRequestTarget target, Location location) {
				if ( location.getComponent() != tree ) {
					Event event = location.getModelObject();
					tree.expand( event );
				}
			}

			@Override
			public void onDrop(AjaxRequestTarget target, Transfer transfer, Location location) throws Reject {
				if ( location.getComponent() == tree ) {
					provider.add( operate( transfer ) );
				} else {
					Event event = location.getModelObject();
					if ( event.isAncestor( transfer.getData() ) ) {
						transfer.reject();
					}

					switch ( location.getAnchor() ) {
					case CENTER:
						if ( event == transfer.getData() ) {
							transfer.reject();
						}
						provider.add( operate( transfer ), event );

						tree.expand( event );
						break;
					case TOP:
						provider.addBefore( operate( transfer ), event );
						break;
					case BOTTOM:
						provider.addAfter( operate( transfer ), event );
						break;
					default:
						transfer.reject();
					}
				}
				target.add( tree );
			}
		}.dropCenter( "span.tree-content, div.treeContainer" ).dropTopAndBottom( "div.tree-branch" ) );
		// Note: CSS selector 'or' (comma) doesn't work with prototype < 1.7
		tree.setOutputMarkupId( true );
		add( tree );
		AjaxSubmitLink link = new AjaxSubmitLink( "saveLink" ) {

			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
				if ( regForm.getModel() != null ) {
					
					sessionService.setEventParent( provider.getModelParent() );
					regForm.setEventParent( target );
					close( target );

				} else {
					eventService.saveEvents( provider.getEvents() );
				}

			}

			@Override
			protected void onError(AjaxRequestTarget target, Form<?> form) {
				System.out.println( "ZLEEEEEEEEEEEEEE" );
			}
		};

		link.add( new Image( "saveImage", new ContextRelativeResource( "/images/Page/ButtonSave.png" ) ) );
		add( link );

	}

	public abstract void close(AjaxRequestTarget target);
}